From 976f6fc92c5e643e0a2808d2694e96d0c472f060 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 4 Apr 2005 16:55:15 +0000 Subject: [PATCH] bitkeeper revision 1.1236.1.209 (42517173PR-QieAWB-SNd4qnSxKmMQ) Remove broken atropos and round-robin schedulers. Clean up the scheduler plugin interface a little. Signed-off-by: Keir Fraser --- .rootkeys | 4 - tools/libxc/Makefile | 2 - tools/libxc/xc.h | 14 - tools/libxc/xc_atropos.c | 51 -- tools/libxc/xc_domain.c | 23 +- tools/libxc/xc_rrobin.c | 37 -- tools/python/xen/lowlevel/xc/xc.c | 124 ---- tools/python/xen/xend/XendClient.py | 13 - tools/python/xen/xend/XendDomain.py | 18 - tools/python/xen/xend/XendNode.py | 6 - tools/python/xen/xend/server/SrvDomain.py | 10 - tools/python/xen/xend/server/SrvNode.py | 6 - tools/python/xen/xend/server/SrvUsbif.py | 10 - tools/python/xen/xm/main.py | 34 -- xen/common/Makefile | 3 - xen/common/domain.c | 7 +- xen/common/sched_atropos.c | 695 ---------------------- xen/common/sched_rrobin.c | 227 ------- xen/common/schedule.c | 27 +- xen/include/public/dom0_ops.h | 2 +- xen/include/public/sched_ctl.h | 70 +-- xen/include/xen/sched-if.h | 4 +- 22 files changed, 48 insertions(+), 1339 deletions(-) delete mode 100644 tools/libxc/xc_atropos.c delete mode 100644 tools/libxc/xc_rrobin.c delete mode 100644 xen/common/sched_atropos.c delete mode 100644 xen/common/sched_rrobin.c diff --git a/.rootkeys b/.rootkeys index 1db0f788e9..8bb76d2df1 100644 --- a/.rootkeys +++ b/.rootkeys @@ -712,7 +712,6 @@ 41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h 3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec 3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h -40589968oCfoUlXd460CjVAkBE8IBA tools/libxc/xc_atropos.c 3fbba6dbEVkVMX0JuDFzap9jeaucGA tools/libxc/xc_bvtsched.c 3fbba6dbasJQV-MVElDC0DGSHMiL5w tools/libxc/xc_domain.c 40278d99BLsfUv3qxv0I8C1sClZ0ow tools/libxc/xc_elf.h @@ -729,7 +728,6 @@ 3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c 3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h 42337174PxyzzPk62raDiYCIsfStDg tools/libxc/xc_ptrace.c -40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c 41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c 40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile 40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c @@ -1208,9 +1206,7 @@ 3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c 4051bcecFeq4DE70p4zGO5setf47CA xen/common/physdev.c 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/common/resource.c -4064773cJ31vZt-zhbSoxqft1Jaw0w xen/common/sched_atropos.c 40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c -40589968be_t_n0-w6ggceW7h-sx0w xen/common/sched_rrobin.c 3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c 3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c 3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index cc72924724..fecb4bfa58 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -16,7 +16,6 @@ vpath %c $(XEN_LIBXUTIL) INCLUDES += -I $(XEN_LIBXUTIL) SRCS := -SRCS += xc_atropos.c SRCS += xc_bvtsched.c SRCS += xc_domain.c SRCS += xc_evtchn.c @@ -30,7 +29,6 @@ SRCS += xc_misc.c SRCS += xc_physdev.c SRCS += xc_private.c SRCS += xc_ptrace.c -SRCS += xc_rrobin.c SRCS += xc_vmx_build.c CFLAGS += -Wall diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h index 77081f329a..0faa23c957 100644 --- a/tools/libxc/xc.h +++ b/tools/libxc/xc.h @@ -257,20 +257,6 @@ int xc_bvtsched_domain_get(int xc_handle, long long *warpl, long long *warpu); -int xc_atropos_domain_set(int xc_handle, - u32 domid, - u64 period, u64 slice, u64 latency, - int xtratime); - -int xc_atropos_domain_get(int xc_handle, - u32 domid, - u64* period, u64 *slice, u64 *latency, - int *xtratime); - -int xc_rrobin_global_set(int xc_handle, u64 slice); - -int xc_rrobin_global_get(int xc_handle, u64 *slice); - typedef evtchn_status_t xc_evtchn_status_t; /* diff --git a/tools/libxc/xc_atropos.c b/tools/libxc/xc_atropos.c deleted file mode 100644 index 13d07ca440..0000000000 --- a/tools/libxc/xc_atropos.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * xc_atropos.c - * - * API for manipulating parameters of the Atropos scheduler. - * - * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge. - */ - -#include "xc_private.h" - -int xc_atropos_domain_set(int xc_handle, - u32 domid, u64 period, u64 slice, u64 latency, - int xtratime) -{ - dom0_op_t op; - struct atropos_adjdom *p = &op.u.adjustdom.u.atropos; - - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t)domid; - op.u.adjustdom.sched_id = SCHED_ATROPOS; - op.u.adjustdom.direction = SCHED_INFO_PUT; - - p->nat_period = period; - p->nat_slice = slice; - p->latency = latency; - p->xtratime = xtratime; - - return do_dom0_op(xc_handle, &op); -} - -int xc_atropos_domain_get(int xc_handle, u32 domid, u64 *period, - u64 *slice, u64 *latency, int *xtratime) -{ - dom0_op_t op; - int ret; - struct atropos_adjdom *p = &op.u.adjustdom.u.atropos; - - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t)domid; - op.u.adjustdom.sched_id = SCHED_ATROPOS; - op.u.adjustdom.direction = SCHED_INFO_GET; - - ret = do_dom0_op(xc_handle, &op); - - *period = p->nat_period; - *slice = p->nat_slice; - *latency = p->latency; - *xtratime = p->xtratime; - - return ret; -} diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d907a699e0..cdef14886c 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -177,10 +177,10 @@ int xc_domain_setcpuweight(int xc_handle, int ret; /* Figure out which scheduler is currently used: */ - if((ret = xc_sched_id(xc_handle, &sched_id))) + if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 ) return ret; - switch(sched_id) + switch ( sched_id ) { case SCHED_BVT: { @@ -192,30 +192,21 @@ int xc_domain_setcpuweight(int xc_handle, /* Preserve all the scheduling parameters apart of MCU advance. */ - if((ret = xc_bvtsched_domain_get(xc_handle, domid, &mcuadv, - &warpback, &warpvalue, &warpl, &warpu))) + if ( (ret = xc_bvtsched_domain_get( + xc_handle, domid, &mcuadv, + &warpback, &warpvalue, &warpl, &warpu)) != 0 ) return ret; /* The MCU advance is inverse of the weight. Default value of the weight is 1, default mcuadv 10. The scaling factor is therefore 10. */ - if(weight > 0) mcuadv = 10 / weight; + if ( weight > 0 ) + mcuadv = 10 / weight; ret = xc_bvtsched_domain_set(xc_handle, domid, mcuadv, warpback, warpvalue, warpl, warpu); break; } - - case SCHED_RROBIN: - { - /* The weight cannot be set for RRobin */ - break; - } - case SCHED_ATROPOS: - { - /* TODO - can we set weights in Atropos? */ - break; - } } return ret; diff --git a/tools/libxc/xc_rrobin.c b/tools/libxc/xc_rrobin.c deleted file mode 100644 index ad37962f3b..0000000000 --- a/tools/libxc/xc_rrobin.c +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * xc_rrobin.c - * - * API for manipulating parameters of the Round Robin scheduler - * - * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge. - */ - -#include "xc_private.h" - -int xc_rrobin_global_set(int xc_handle, u64 slice) -{ - dom0_op_t op; - op.cmd = DOM0_SCHEDCTL; - op.u.schedctl.sched_id = SCHED_RROBIN; - op.u.schedctl.direction = SCHED_INFO_PUT; - - op.u.schedctl.u.rrobin.slice = slice; - return do_dom0_op(xc_handle, &op); -} - - -int xc_rrobin_global_get(int xc_handle, u64 *slice) -{ - dom0_op_t op; - int ret; - - op.cmd = DOM0_SCHEDCTL; - op.u.schedctl.sched_id = SCHED_RROBIN; - op.u.schedctl.direction = SCHED_INFO_GET; - - ret = do_dom0_op(xc_handle, &op); - - *slice = op.u.schedctl.u.rrobin.slice; - - return ret; -} diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 2e425d4887..a474c4a888 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -800,76 +800,6 @@ static PyObject *pyxc_physinfo(PyObject *self, "cpu_khz", info.cpu_khz); } -static PyObject *pyxc_atropos_domain_set(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - u32 domid; - u64 period, slice, latency; - int xtratime; - - static char *kwd_list[] = { "dom", "period", "slice", "latency", - "xtratime", NULL }; - - if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLi", kwd_list, &domid, - &period, &slice, &latency, &xtratime) ) - return NULL; - - if ( xc_atropos_domain_set(xc->xc_handle, domid, period, slice, - latency, xtratime) != 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; -} - -static PyObject *pyxc_atropos_domain_get(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - u32 domid; - u64 period, slice, latency; - int xtratime; - - static char *kwd_list[] = { "dom", NULL }; - - if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) ) - return NULL; - - if ( xc_atropos_domain_get( xc->xc_handle, domid, &period, - &slice, &latency, &xtratime ) ) - return PyErr_SetFromErrno(xc_error); - - return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}", - "domain", domid, - "period", period, - "slice", slice, - "latency", latency, - "xtratime", xtratime); -} - - -static PyObject *pyxc_rrobin_global_set(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - u64 slice; - - static char *kwd_list[] = { "slice", NULL }; - - if( !PyArg_ParseTupleAndKeywords(args, kwds, "L", kwd_list, &slice) ) - return NULL; - - if ( xc_rrobin_global_set(xc->xc_handle, slice) != 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; -} - static PyObject *pyxc_shadow_control(PyObject *self, PyObject *args, PyObject *kwds) @@ -892,22 +822,6 @@ static PyObject *pyxc_shadow_control(PyObject *self, return zero; } -static PyObject *pyxc_rrobin_global_get(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - u64 slice; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( xc_rrobin_global_get(xc->xc_handle, &slice) != 0 ) - return PyErr_SetFromErrno(xc_error); - - return Py_BuildValue("{s:L}", "slice", slice); -} - static PyObject *pyxc_domain_setmaxmem(PyObject *self, PyObject *args, PyObject *kwds) @@ -1079,44 +993,6 @@ static PyMethodDef pyxc_methods[] = { " warpl [long]: Warp limit,\n" }, - { "atropos_domain_set", - (PyCFunction)pyxc_atropos_domain_set, - METH_KEYWORDS, "\n" - "Set the scheduling parameters for a domain when running with Atropos.\n" - " dom [int]: domain to set\n" - " period [long]: domain's scheduling period\n" - " slice [long]: domain's slice per period\n" - " latency [long]: wakeup latency hint\n" - " xtratime [int]: boolean\n" - "Returns: [int] 0 on success; -1 on error.\n" }, - - { "atropos_domain_get", - (PyCFunction)pyxc_atropos_domain_get, - METH_KEYWORDS, "\n" - "Get the current scheduling parameters for a domain when running with\n" - "the Atropos scheduler." - " dom [int]: domain to query\n" - "Returns: [dict]\n" - " domain [int]: domain ID\n" - " period [long]: scheduler period\n" - " slice [long]: CPU reservation per period\n" - " latency [long]: unblocking latency hint\n" - " xtratime [int] : 0 if not using slack time, nonzero otherwise\n" }, - - { "rrobin_global_set", - (PyCFunction)pyxc_rrobin_global_set, - METH_KEYWORDS, "\n" - "Set Round Robin scheduler slice.\n" - " slice [long]: Round Robin scheduler slice\n" - "Returns: [int] 0 on success, throws an exception on failure\n" }, - - { "rrobin_global_get", - (PyCFunction)pyxc_rrobin_global_get, - METH_KEYWORDS, "\n" - "Get Round Robin scheduler settings\n" - "Returns [dict]:\n" - " slice [long]: Scheduler time slice.\n" }, - { "evtchn_alloc_unbound", (PyCFunction)pyxc_evtchn_alloc_unbound, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 8fbe3fa203..e25bababf5 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -189,11 +189,6 @@ class Xend: def xend_node_log(self): return self.xendGet(self.nodeurl('log')) - def xend_node_cpu_rrobin_slice_set(self, slice): - return self.xendPost(self.nodeurl(), - {'op' : 'cpu_rrobin_slice_set', - 'slice' : slice }) - def xend_node_cpu_bvt_slice_set(self, ctx_allow): return self.xendPost(self.nodeurl(), {'op' : 'cpu_bvt_slice_set', @@ -265,14 +260,6 @@ class Xend: 'warpl' : warpl, 'warpu' : warpu }) - def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime): - return self.xendPost(self.domainurl(id), - {'op' : 'cpu_atropos_set', - 'period' : period, - 'slice' : slice, - 'latency' : latency, - 'xtratime': xtratime }) - def xend_domain_maxmem_set(self, id, memory): return self.xendPost(self.domainurl(id), { 'op' : 'maxmem_set', diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 8842c480cd..7f5218bff1 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -642,24 +642,6 @@ class XendDomain: except Exception, ex: raise XendError(str(ex)) - def domain_cpu_atropos_set(self, id, period, slice, latency, xtratime): - """Set Atropos scheduler parameters for a domain. - """ - dominfo = self.domain_lookup(id) - try: - return xc.atropos_domain_set(dominfo.dom, period, slice, latency, xtratime) - except Exception, ex: - raise XendError(str(ex)) - - def domain_cpu_atropos_get(self, id): - """Get Atropos scheduler parameters for a domain. - """ - dominfo = self.domain_lookup(id) - try: - return xc.atropos_domain_get(dominfo.dom) - except Exception, ex: - raise XendError(str(ex)) - def domain_device_create(self, id, devconfig): """Create a new device for a domain. diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 5fff0f62dd..d915f0ba0f 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -30,12 +30,6 @@ class XendNode: def cpu_bvt_slice_get(self): return self.xc.bvtsched_global_get() - def cpu_rrobin_slice_set(self, slice): - return self.xc.rrobin_global_set(slice=slice) - - def cpu_rrobin_slice_get(self): - return self.xc.rrobin_global_get() - def info(self): return self.nodeinfo() + self.physinfo() diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index aeeb4b0c05..698da4624c 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -107,16 +107,6 @@ class SrvDomain(SrvDir): val = fn(req.args, {'dom': self.dom.id}) return val - def op_cpu_atropos_set(self, op, req): - fn = FormFn(self.xd.domain_cpu_atropos_set, - [['dom', 'str'], - ['period', 'int'], - ['slice', 'int'], - ['latency', 'int'], - ['xtratime', 'int']]) - val = fn(req.args, {'dom': self.dom.id}) - return val - def op_maxmem_set(self, op, req): fn = FormFn(self.xd.domain_maxmem_set, [['dom', 'str'], diff --git a/tools/python/xen/xend/server/SrvNode.py b/tools/python/xen/xend/server/SrvNode.py index c1b3ab560e..fe0834bb0d 100644 --- a/tools/python/xen/xend/server/SrvNode.py +++ b/tools/python/xen/xend/server/SrvNode.py @@ -25,12 +25,6 @@ class SrvNode(SrvDir): val = self.xn.reboot() return val - def op_cpu_rrobin_slice_set(self, op, req): - fn = FormFn(self.xn.cpu_rrobin_slice_set, - [['slice', 'int']]) - val = fn(req.args, {}) - return val - def op_cpu_bvt_slice_set(self, op, req): fn = FormFn(self.xn.cpu_bvt_slice_set, [['ctx_allow', 'int']]) diff --git a/tools/python/xen/xend/server/SrvUsbif.py b/tools/python/xen/xend/server/SrvUsbif.py index bdd57524ce..0062ab531b 100644 --- a/tools/python/xen/xend/server/SrvUsbif.py +++ b/tools/python/xen/xend/server/SrvUsbif.py @@ -132,16 +132,6 @@ class SrvDomain(SrvDir): val = fn(req.args, {'dom': self.dom.id}) return val - def op_cpu_atropos_set(self, op, req): - fn = FormFn(self.xd.domain_cpu_atropos_set, - [['dom', 'str'], - ['period', 'int'], - ['slice', 'int'], - ['latency', 'int'], - ['xtratime', 'int']]) - val = fn(req.args, {'dom': self.dom.id}) - return val - def op_maxmem_set(self, op, req): fn = FormFn(self.xd.domain_maxmem_set, [['dom', 'str'], diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 43e12e3892..e4c7151c32 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -566,40 +566,6 @@ class ProgBvtslice(Prog): xm.prog(ProgBvtslice) - -class ProgAtropos(Prog): - group = 'scheduler' - name= "atropos" - info = """Set atropos parameters.""" - - def help(self, args): - print args[0], "DOM PERIOD SLICE LATENCY XTRATIME" - print "\nSet atropos parameters." - - def main(self, args): - if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0]) - dom = args[1] - v = map(int, args[2:6]) - server.xend_domain_cpu_atropos_set(dom, *v) - -xm.prog(ProgAtropos) - -class ProgRrobin(Prog): - group = 'scheduler' - name = "rrobin" - info = """Set round robin slice.""" - - def help(self, args): - print args[0], "SLICE" - print "\nSet round robin scheduler slice." - - def main(self, args): - if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0]) - rrslice = int(args[1]) - server.xend_node_rrobin_set(rrslice) - -xm.prog(ProgRrobin) - class ProgInfo(Prog): group = 'host' name = "info" diff --git a/xen/common/Makefile b/xen/common/Makefile index f8868ece6f..e832864584 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -15,9 +15,6 @@ ifneq ($(trace),y) OBJS := $(subst trace.o,,$(OBJS)) endif -OBJS := $(subst sched_atropos.o,,$(OBJS)) -OBJS := $(subst sched_rrobin.o,,$(OBJS)) - default: common.o common.o: $(OBJS) $(LD) $(LDFLAGS) -r -o common.o $(OBJS) diff --git a/xen/common/domain.c b/xen/common/domain.c index b79c42e0ec..dff6c033af 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -326,13 +326,10 @@ long do_boot_vcpu(unsigned long vcpu, full_execution_context_t *ctxt) arch_do_boot_vcpu(ed); - sched_add_domain(ed); - if ( (rc = arch_set_info_guest(ed, c)) != 0 ) - { - sched_rem_domain(ed); goto out; - } + + sched_add_domain(ed); /* domain_unpause_by_systemcontroller */ if ( test_and_clear_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) diff --git a/xen/common/sched_atropos.c b/xen/common/sched_atropos.c deleted file mode 100644 index 9b7c071b16..0000000000 --- a/xen/common/sched_atropos.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * atropos.c - * --------- - * - * Copyright (c) 1994 University of Cambridge Computer Laboratory. - * This is part of Nemesis; consult your contract for terms and conditions. - * - * ID : $Id: atropos.c 1.1 Tue, 13 Apr 1999 13:30:49 +0100 dr10009 $ - * - * This is the "atropos" CPU scheduler. - */ - -/* Ported to Xen's generic scheduler interface by Mark Williamson - * these modifications are (C) 2004 Intel Research Cambridge - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ATROPOS_TASK_UNBLOCKED 16 -#define ATROPOS_TASK_WAIT 32 -#define ATROPOS_TASK_BLOCKED 48 - -/* Atropos-specific per-domain data */ -struct at_dom_info -{ - /* MAW Xen additions */ - struct domain *owner; /* the domain this data belongs to */ - struct list_head run_list; /* runqueue */ - struct list_head waitq; /* wait queue */ - - /* (what remains of) the original fields */ - - s_time_t deadline; /* Next deadline */ - s_time_t prevddln; /* Previous deadline */ - - s_time_t remain; /* Time remaining this period */ - s_time_t period; /* Current period of time allocation */ - s_time_t nat_period; /* Natural period */ - s_time_t slice; /* Current length of allocation */ - s_time_t nat_slice; /* Natural length of allocation */ - s_time_t latency; /* Unblocking latency */ - - int xtratime; /* Prepared to accept extra time? */ - int state; /* Keeps Atropos domain state */ -}; - -/* Atropos-specific per-CPU data */ -struct at_cpu_info -{ - struct list_head runq; - struct list_head waitq; -}; - - -#define DOM_INFO(_p) ((struct at_dom_info *)((_p)->sched_priv)) -#define CPU_INFO(_c) ((struct at_cpu_info *)((schedule_data[_c]).sched_priv)) -#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq) -#define RUNQ(cpu) (&CPU_INFO(cpu)->runq) -#define RUNLIST(_d) (&DOM_INFO(_d)->run_list) - -#define BESTEFFORT_QUANTUM MILLISECS(5) - -static void at_dump_cpu_state(int cpu); - -static inline void __add_to_runqueue_head(struct domain *d) -{ - list_add(RUNLIST(d), RUNQ(d->processor)); -} - -static inline void __add_to_runqueue_tail(struct domain *d) -{ - list_add_tail(RUNLIST(d), RUNQ(d->processor)); -} - -static inline void __del_from_runqueue(struct domain *d) -{ - struct list_head *runlist = RUNLIST(d); - list_del(runlist); - runlist->next = NULL; -} - -static inline int __task_on_runqueue(struct domain *d) -{ - return (RUNLIST(d))->next != NULL; -} - - -/** calculate the length of a linked list */ -static int q_len(struct list_head *q) -{ - int i = 0; - struct at_dom_info *tmp; - list_for_each_entry ( tmp, q, waitq ) - i++; - return i; -} - - -/** waitq_el - get the domain that owns a wait queue list element */ -static inline struct domain *waitq_el(struct list_head *l) -{ - struct at_dom_info *inf; - inf = list_entry(l, struct at_dom_info, waitq); - return inf->owner; -} - - -/* - * requeue - * - * Places the specified domain on the appropriate queue. - * The wait queue is ordered by the time at which the domain - * will receive more CPU time. If a domain has no guaranteed time - * left then the domain will be placed on the WAIT queue until - * its next period. - * - * Note that domains can be on the wait queue with remain > 0 - * as a result of being blocked for a short time. - * These are scheduled in preference to domains with remain < 0 - * in an attempt to improve interactive performance. - */ -static void requeue(struct domain *sdom) -{ - struct at_dom_info *i, *inf = DOM_INFO(sdom); - - if ( !domain_runnable(sdom) ) - return; - - if ( (inf->state == ATROPOS_TASK_WAIT) || - (inf->state == ATROPOS_TASK_UNBLOCKED) ) - { - list_for_each_entry ( i, WAITQ(sdom->processor), waitq ) - { - if ( i->deadline > inf->deadline ) - { - __list_add(&inf->waitq, i->waitq.prev, &i->waitq); - break; - } - } - - if ( &i->waitq == WAITQ(sdom->processor) ) - list_add_tail(&inf->waitq, WAITQ(sdom->processor)); - } - else if ( domain_runnable(sdom) ) - { - list_for_each_entry ( i, RUNQ(sdom->processor), run_list ) - { - if ( (i->deadline > inf->deadline) || is_idle_task(i->owner) ) - { - __list_add(&inf->run_list, i->run_list.prev, &i->run_list); - break; - } - } - - if ( &i->waitq == RUNQ(sdom->processor) ) - list_add_tail(&inf->run_list, RUNQ(sdom->processor)); - } - /* silently ignore tasks in other states like BLOCKED, DYING, STOPPED, etc - * - they shouldn't be on any queue */ -} - -/** at_alloc_task - allocate private info for a task */ -static int at_alloc_task(struct domain *p) -{ - ASSERT(p != NULL); - - p->sched_priv = xmalloc(struct at_dom_info); - if ( p->sched_priv == NULL ) - return -1; - - return 0; -} - - -/* prepare a task to be added to scheduling */ -static void at_add_task(struct domain *p) -{ - s_time_t now = NOW(); - - ASSERT( p->sched_priv != NULL ); - - DOM_INFO(p)->owner = p; - p->lastschd = now; - - /* DOM 0's parameters must be set here for it to boot the system! */ - if(p->id == 0) - { - DOM_INFO(p)->remain = MILLISECS(15); - DOM_INFO(p)->nat_period = - DOM_INFO(p)->period = MILLISECS(20); - DOM_INFO(p)->nat_slice = - DOM_INFO(p)->slice = MILLISECS(15); - DOM_INFO(p)->latency = MILLISECS(5); - DOM_INFO(p)->xtratime = 1; - DOM_INFO(p)->deadline = now; - DOM_INFO(p)->prevddln = now; - } - else /* other domains run basically best effort unless otherwise set */ - { - DOM_INFO(p)->remain = 0; - DOM_INFO(p)->nat_period = - DOM_INFO(p)->period = SECONDS(10); - DOM_INFO(p)->nat_slice = - DOM_INFO(p)->slice = MILLISECS(10); - DOM_INFO(p)->latency = SECONDS(10); - DOM_INFO(p)->xtratime = 1; - DOM_INFO(p)->deadline = now; -// DOM_INFO(p)->deadline = now + SECONDS(10); - DOM_INFO(p)->prevddln = 0; - } - - INIT_LIST_HEAD(&(DOM_INFO(p)->run_list)); - INIT_LIST_HEAD(&(DOM_INFO(p)->waitq)); -} - -/** - * dequeue - remove a domain from any queues it is on. - * @sdom: the task to remove - */ -static void dequeue(struct domain *sdom) -{ - struct at_dom_info *inf = DOM_INFO(sdom); - - ASSERT(sdom->id != IDLE_DOMAIN_ID); - - /* just delete it from all the queues! */ - list_del(&inf->waitq); - INIT_LIST_HEAD(&inf->waitq); - - - if(__task_on_runqueue(sdom)) - __del_from_runqueue(sdom); -} - - -/* - * unblock - * - * This function deals with updating the sdom for a domain - * which has just been unblocked. - * - * Xen's Atropos treats unblocking slightly differently to Nemesis: - * - * - "Short blocking" domains (i.e. that unblock before their deadline has - * expired) are treated the same as in nemesis (put on the wait queue and - * given preferential treatment in selecting domains for extra time). - * - * - "Long blocking" domains do not simply have their period truncated to their - * unblocking latency as before but also have their slice recomputed to be the - * same fraction of their new period. Each time the domain is scheduled, the - * period and slice are doubled until they reach their original ("natural") - * values, as set by the user (and stored in nat_period and nat_slice). The - * idea is to give better response times to unblocking whilst preserving QoS - * guarantees to other domains. - */ -static void unblock(struct domain *sdom) -{ - s_time_t time = NOW(); - struct at_dom_info *inf = DOM_INFO(sdom); - - dequeue(sdom); - - /* We distinguish two cases... short and long blocks */ - if ( inf->deadline < time ) - { - /* Long blocking case */ - - /* The sdom has passed its deadline since it was blocked. - Give it its new deadline based on the latency value. */ - inf->prevddln = time; - - /* Scale the scheduling parameters as requested by the latency hint. */ - inf->deadline = time + inf->latency; - inf->slice = inf->nat_slice / ( inf->nat_period / inf->latency ); - inf->period = inf->latency; - inf->remain = inf->slice; - } - else - { - /* Short blocking case */ - - /* We leave REMAIN intact, but put this domain on the WAIT - queue marked as recently unblocked. It will be given - priority over other domains on the wait queue until while - REMAIN>0 in a generous attempt to help it make up for its - own foolishness. */ - if(inf->remain > 0) - inf->state = ATROPOS_TASK_UNBLOCKED; - else - inf->state = ATROPOS_TASK_WAIT; - } - - requeue(sdom); -} - - -static int at_init_idle_task(struct domain *p) -{ - if(at_alloc_task(p) < 0) return -1; - - at_add_task(p); - - dequeue(p); - requeue(p); - - return 0; -} - - -static void block(struct domain* sdom) -{ - DOM_INFO(sdom)->state = ATROPOS_TASK_BLOCKED; - dequeue(sdom); - requeue(sdom); -} - - -/** - * ATROPOS - main scheduler function - */ -struct task_slice ksched_scheduler(s_time_t time) -{ - struct domain *cur_sdom = current; /* Current sdom */ - s_time_t newtime; - s_time_t ranfor; /* How long the domain ran */ - struct domain *sdom; /* tmp. scheduling domain */ - int cpu = cur_sdom->processor; /* current CPU */ - struct at_dom_info *cur_info; - static unsigned long waitq_rrobin = 0; - int i; - struct task_slice ret; - - - cur_info = DOM_INFO(cur_sdom); - - ASSERT( cur_sdom != NULL); - - /* If we were spinning in the idle loop, there is no current - * domain to deschedule. */ - if (is_idle_task(cur_sdom)) - goto deschedule_done; - - /***************************** - * - * Deschedule the current scheduling domain - * - ****************************/ - - /* Record the time the domain was preempted and for how long it - ran. Work out if the domain is going to be blocked to save - some pointless queue shuffling */ - cur_sdom->lastdeschd = time; - - ranfor = (time - cur_sdom->lastschd); - - dequeue(cur_sdom); - - if ( domain_runnable(cur_sdom) || - (cur_info->state == ATROPOS_TASK_UNBLOCKED) ) - { - - /* In this block, we are doing accounting for an sdom which has - been running in contracted time. Note that this could now happen - even if the domain is on the wait queue (i.e. if it blocked) */ - - /* Deduct guaranteed time from the domain */ - cur_info->remain -= ranfor; - - /* If guaranteed time has run out... */ - if ( cur_info->remain <= 0 ) - { - /* Move domain to correct position in WAIT queue */ - /* XXX sdom_unblocked doesn't need this since it is - already in the correct place. */ - cur_info->state = ATROPOS_TASK_WAIT; - } - } - - requeue(cur_sdom); - - deschedule_done: - /***************************** - * - * We have now successfully descheduled the current sdom. - * The next task is the allocate CPU time to any sdom it is due to. - * - ****************************/ - cur_sdom = NULL; - - /***************************** - * - * Allocate CPU time to any waiting domains who have passed their - * period deadline. If necessary, move them to run queue. - * - ****************************/ - - while(!list_empty(WAITQ(cpu)) && - DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) - { - - struct at_dom_info *inf = DOM_INFO(sdom); - dequeue(sdom); - - if ( inf->period != inf->nat_period ) - { - /* This domain has had its parameters adjusted as a result of - * unblocking and they need to be adjusted before requeuing it */ - inf->slice *= 2; - inf->period *= 2; - - if ( inf->period > inf->nat_period ) - { - inf->period = inf->nat_period; - inf->slice = inf->nat_slice; - } - } - - /* Domain begins a new period and receives a slice of CPU - * If this domain has been blocking then throw away the - * rest of it's remain - it can't be trusted */ - if (inf->remain > 0) - inf->remain = inf->slice; - else - inf->remain += inf->slice; - - inf->prevddln = inf->deadline; - inf->deadline += inf->period; - - if ( inf->remain <= 0 ) - inf->state = ATROPOS_TASK_WAIT; - - /* Place on the appropriate queue */ - requeue(sdom); - } - - /***************************** - * - * Next we need to pick an sdom to run. - * If anything is actually 'runnable', we run that. - * If nothing is, we pick a waiting sdom to run optimistically. - * If there aren't even any of those, we have to spin waiting for an - * event or a suitable time condition to happen. - * - ****************************/ - - /* we guarantee there's always something on the runqueue */ - cur_info = list_entry(RUNQ(cpu)->next, - struct at_dom_info, run_list); - - cur_sdom = cur_info->owner; - newtime = time + cur_info->remain; - - /* MAW - the idle domain is always on the run queue. We run from the - * runqueue if it's NOT the idle domain or if there's nothing on the wait - * queue */ - if (cur_sdom->id == IDLE_DOMAIN_ID && !list_empty(WAITQ(cpu))) - { - struct at_dom_info *inf; - - /* Try running a domain on the WAIT queue - this part of the - scheduler isn't particularly efficient but then again, we - don't have any guaranteed domains to worry about. */ - - /* See if there are any unblocked domains on the WAIT - queue who we can give preferential treatment to. */ - - list_for_each_entry ( inf, WAITQ(cpu), waitq ) - { - sdom = inf->owner; - - if (inf->state == ATROPOS_TASK_UNBLOCKED) - { - cur_sdom = sdom; - cur_info = inf; - newtime = time + inf->remain; - goto found; - } - } - - /* init values needed to approximate round-robin for slack time */ - i = 0; - if ( waitq_rrobin >= q_len(WAITQ(cpu))) - waitq_rrobin = 0; - - - /* Last chance: pick a domain on the wait queue with the XTRA - flag set. The NEXT_OPTM field is used to cheaply achieve - an approximation of round-robin order */ - list_for_each_entry ( inf, WAITQ(cpu), waitq ) - { - sdom = inf->owner; - - if (inf->xtratime && i >= waitq_rrobin) - { - cur_sdom = sdom; - cur_info = inf; - newtime = time + BESTEFFORT_QUANTUM; - waitq_rrobin = i + 1; /* set this value ready for next */ - goto found; - } - - i++; - } - } - - found: - /********************** - * - * We now have to work out the time when we next need to - * make a scheduling decision. We set the alarm timer - * to cause an interrupt at that time. - * - **********************/ - -#define MIN(x,y) ( ( x < y ) ? x : y ) -#define MAX(x,y) ( ( x > y ) ? x : y ) - - /* If we might be able to run a waiting domain before this one has */ - /* exhausted its time, cut short the time allocation */ - if (!list_empty(WAITQ(cpu))) - { - newtime = MIN(newtime, - DOM_INFO(waitq_el(WAITQ(cpu)->next))->deadline); - } - - /* don't allow pointlessly small time slices */ - newtime = MAX(newtime, time + BESTEFFORT_QUANTUM); - - ret.task = cur_sdom; - ret.time = newtime - time; - - TRACE_1D(0, cur_sdom->id); - - return ret; -} - - -/* set up some private data structures */ -static int at_init_scheduler() -{ - int i; - - for ( i = 0; i < NR_CPUS; i++ ) - { - schedule_data[i].sched_priv = xmalloc(sizeof(struct at_cpu_info)); - if ( schedule_data[i].sched_priv == NULL ) - return -1; - INIT_LIST_HEAD(WAITQ(i)); - INIT_LIST_HEAD(RUNQ(i)); - } - - return 0; -} - - -/* print relevant per-domain info for a run queue dump */ -static void at_dump_runq_el(struct domain *p) -{ - printk("lastschd = %llu, xtratime = %d ", - p->lastschd, DOM_INFO(p)->xtratime); -} - - -/* dump relevant per-cpu state for a run queue dump */ -static void at_dump_cpu_state(int cpu) -{ - struct list_head *queue; - int loop = 0; - struct at_dom_info *d_inf; - struct domain *d; - - queue = RUNQ(cpu); - printk("\nRUNQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, - (unsigned long) queue->next, (unsigned long) queue->prev); - - list_for_each_entry ( d_inf, queue, run_list ) - { - d = d_inf->owner; - printk("%3d: %d has=%c ", loop++, d->id, - test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); - at_dump_runq_el(d); - printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); - printk(" l: %lx n: %lx p: %lx\n", - (unsigned long)&d_inf->run_list, - (unsigned long)d_inf->run_list.next, - (unsigned long)d_inf->run_list.prev); - } - - - queue = WAITQ(cpu); - printk("\nWAITQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, - (unsigned long) queue->next, (unsigned long) queue->prev); - - list_for_each_entry ( d_inf, queue, waitq ) - { - d = d_inf->owner; - printk("%3d: %d has=%c ", loop++, d->id, - test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); - at_dump_runq_el(d); - printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); - printk(" l: %lx n: %lx p: %lx\n", - (unsigned long)&d_inf->waitq, - (unsigned long)d_inf->waitq.next, - (unsigned long)d_inf->waitq.prev); - } - -} - -/* set or fetch domain scheduling parameters */ -static int at_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) -{ - if ( cmd->direction == SCHED_INFO_PUT ) - { - /* sanity checking! */ - if( cmd->u.atropos.latency > cmd->u.atropos.nat_period - || cmd->u.atropos.latency == 0 - || cmd->u.atropos.nat_slice > cmd->u.atropos.nat_period ) - return -EINVAL; - - DOM_INFO(p)->nat_period = cmd->u.atropos.nat_period; - DOM_INFO(p)->nat_slice = cmd->u.atropos.nat_slice; - DOM_INFO(p)->latency = cmd->u.atropos.latency; - DOM_INFO(p)->xtratime = !!cmd->u.atropos.xtratime; - } - else if ( cmd->direction == SCHED_INFO_GET ) - { - cmd->u.atropos.nat_period = DOM_INFO(p)->nat_period; - cmd->u.atropos.nat_slice = DOM_INFO(p)->nat_slice; - cmd->u.atropos.latency = DOM_INFO(p)->latency; - cmd->u.atropos.xtratime = DOM_INFO(p)->xtratime; - } - - return 0; -} - -/* free memory associated with a task */ -static void at_free_task(struct domain *p) -{ - xfree( DOM_INFO(p) ); -} - - -/* print decoded domain private state value (if known) */ -static int at_prn_state(int state) -{ - int ret = 0; - - switch(state) - { - case ATROPOS_TASK_UNBLOCKED: - printk("Unblocked"); - break; - case ATROPOS_TASK_WAIT: - printk("Wait"); - break; - default: - ret = -1; - } - - return ret; -} - -struct scheduler sched_atropos_def = { - .name = "Atropos Soft Real Time Scheduler", - .opt_name = "atropos", - .sched_id = SCHED_ATROPOS, - .init_scheduler = at_init_scheduler, - .init_idle_task = at_init_idle_task, - .alloc_task = at_alloc_task, - .add_task = at_add_task, - .free_task = at_free_task, - .wake = unblock, - .sleep = block, - .do_schedule = ksched_scheduler, - .adjdom = at_adjdom, - .dump_cpu_state = at_dump_cpu_state, - .prn_state = at_prn_state, -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/common/sched_rrobin.c b/xen/common/sched_rrobin.c deleted file mode 100644 index a3535ae128..0000000000 --- a/xen/common/sched_rrobin.c +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** - * Round Robin Scheduler for Xen - * - * by Mark Williamson (C) 2004 Intel Research Cambridge - */ - -#include -#include -#include -#include -#include -#include -#include - -#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ - -static s_time_t rr_slice = MILLISECS(10); - -/* Only runqueue pointers and domain pointer*/ -struct rrobin_dom_info -{ - struct list_head run_list; - struct domain *domain; -}; - -#define RR_INFO(d) ((struct rrobin_dom_info *)d->sched_priv) -#define RUNLIST(d) ((struct list_head *)&(RR_INFO(d)->run_list)) -#define RUNQUEUE(cpu) RUNLIST(schedule_data[cpu].idle) - -static inline void __add_to_runqueue_head(struct domain *d) -{ - list_add(RUNLIST(d), RUNQUEUE(d->processor)); -} - -static inline void __add_to_runqueue_tail(struct domain *d) -{ - list_add_tail(RUNLIST(d), RUNQUEUE(d->processor)); -} - -static inline void __del_from_runqueue(struct domain *d) -{ - struct list_head *runlist = RUNLIST(d); - list_del(runlist); - runlist->next = NULL; -} - -static inline int __task_on_runqueue(struct domain *d) -{ - return (RUNLIST(d))->next != NULL; -} - -/* Initialises the runqueues and creates the domain info cache */ -static int rr_init_scheduler() -{ - int i; - - for ( i = 0; i < NR_CPUS; i++ ) - INIT_LIST_HEAD(RUNQUEUE(i)); - - return 0; -} -/* Allocates memory for per domain private scheduling data*/ -static int rr_alloc_task(struct domain *d) -{ - if ( (d->sched_priv = new(struct rrobin_dom_info) == NULL ) - return -1; - memset(d->sched_priv, 0, sizeof(struct rrobin_dom_info)); - return 0; -} - -/* Setup the rr_dom_info */ -static void rr_add_task(struct domain *d) -{ - struct rrobin_dom_info *inf; - RR_INFO(d)->domain = d; - inf = RR_INFO(d); -} - -/* Frees memory used by domain info */ -static void rr_free_task(struct domain *d) -{ - ASSERT(d->sched_priv != NULL); - xfree(d->sched_priv); -} - -/* Initialises idle task */ -static int rr_init_idle_task(struct domain *d) -{ - if ( rr_alloc_task(d) < 0 ) - return -1; - - rr_add_task(d); - - set_bit(DF_RUNNING, &d->flags); - if ( !__task_on_runqueue(d) ) - __add_to_runqueue_head(d); - - return 0; -} - -/* Main scheduling function */ -static struct task_slice rr_do_schedule(s_time_t now) -{ - struct domain *prev = current; - int cpu = current->processor; - struct task_slice ret; - - if ( !is_idle_task(prev) ) - { - __del_from_runqueue(prev); - - if ( domain_runnable(prev) ) - __add_to_runqueue_tail(prev); - } - - ret.task = list_entry(RUNQUEUE(cpu)->next, - struct rrobin_dom_info, - run_list)->domain; - ret.time = rr_slice; - return ret; -} - -/* Set/retrive control parameter(s) */ -static int rr_ctl(struct sched_ctl_cmd *cmd) -{ - if ( cmd->direction == SCHED_INFO_PUT ) - { - rr_slice = cmd->u.rrobin.slice; - } - else /* cmd->direction == SCHED_INFO_GET */ - { - cmd->u.rrobin.slice = rr_slice; - } - - return 0; -} - -static void rr_dump_settings() -{ - printk("rr_slice = %llu ", rr_slice); -} - -static void rr_sleep(struct domain *d) -{ - if ( test_bit(DF_RUNNING, &d->flags) ) - cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ); - else if ( __task_on_runqueue(d) ) - __del_from_runqueue(d); -} - -void rr_wake(struct domain *d) -{ - struct domain *curr; - s_time_t now; - int cpu = d->processor; - - if ( unlikely(__task_on_runqueue(d)) ) - return; - - __add_to_runqueue_head(d); - - now = NOW(); - - curr = schedule_data[cpu].curr; - if ( is_idle_task(curr) ) - cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); -} - - -static void rr_dump_domain(struct domain *d) -{ - printk("%u has=%c ", d->id, - test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); - printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); -} - -static void rr_dump_cpu_state(int i) -{ - struct list_head *queue; - int loop = 0; - struct rrobin_dom_info *d_inf; - - queue = RUNQUEUE(i); - printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, - (unsigned long) queue->next, (unsigned long) queue->prev); - - printk("%3d: ",loop++); - d_inf = list_entry(queue, struct rrobin_dom_info, run_list); - rr_dump_domain(d_inf->domain); - - list_for_each_entry ( d_inf, queue, run_list ) - { - printk("%3d: ",loop++); - rr_dump_domain(d_inf->domain); - } -} - - -struct scheduler sched_rrobin_def = { - .name = "Round-Robin Scheduler", - .opt_name = "rrobin", - .sched_id = SCHED_RROBIN, - - .init_idle_task = rr_init_idle_task, - .alloc_task = rr_alloc_task, - .add_task = rr_add_task, - .free_task = rr_free_task, - .init_scheduler = rr_init_scheduler, - .do_schedule = rr_do_schedule, - .control = rr_ctl, - .dump_settings = rr_dump_settings, - .dump_cpu_state = rr_dump_cpu_state, - .sleep = rr_sleep, - .wake = rr_wake, -}; - - - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/common/schedule.c b/xen/common/schedule.c index ee87faaf93..ac4da68a79 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -242,11 +242,19 @@ void domain_wake(struct exec_domain *ed) /* Block the currently-executing domain until a pertinent event occurs. */ long do_block(void) { - ASSERT(current->domain->id != IDLE_DOMAIN_ID); - current->vcpu_info->evtchn_upcall_mask = 0; - set_bit(EDF_BLOCKED, ¤t->ed_flags); - TRACE_2D(TRC_SCHED_BLOCK, current->domain->id, current); - __enter_scheduler(); + struct exec_domain *ed = current; + + TRACE_2D(TRC_SCHED_BLOCK, ed->domain->id, ed); + + ed->vcpu_info->evtchn_upcall_mask = 0; + set_bit(EDF_BLOCKED, &ed->ed_flags); + + /* Check for events /after/ blocking: avoids wakeup waiting race. */ + if ( event_pending(ed) ) + clear_bit(EDF_BLOCKED, &ed->ed_flags); + else + __enter_scheduler(); + return 0; } @@ -371,15 +379,6 @@ static void __enter_scheduler(void) ASSERT(!in_irq()); - if ( test_bit(EDF_BLOCKED, &prev->ed_flags) ) - { - /* This check is needed to avoid a race condition. */ - if ( event_pending(prev) ) - clear_bit(EDF_BLOCKED, &prev->ed_flags); - else - SCHED_OP(do_block, prev); - } - prev->cpu_time += now - prev->lastschd; /* get policy-specific decision on scheduling... */ diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 36a424e709..cf359f00e9 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -19,7 +19,7 @@ * This makes sure that old versions of dom0 tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define DOM0_INTERFACE_VERSION 0xAAAA1003 +#define DOM0_INTERFACE_VERSION 0xAAAA1004 /************************************************************************/ diff --git a/xen/include/public/sched_ctl.h b/xen/include/public/sched_ctl.h index bd6a717521..ac376d4226 100644 --- a/xen/include/public/sched_ctl.h +++ b/xen/include/public/sched_ctl.h @@ -1,4 +1,4 @@ -/** +/****************************************************************************** * Generic scheduler control interface. * * Mark Williamson, (C) 2004 Intel Research Cambridge @@ -7,13 +7,10 @@ #ifndef __XEN_PUBLIC_SCHED_CTL_H__ #define __XEN_PUBLIC_SCHED_CTL_H__ -/* Scheduler types */ +/* Scheduler types. */ #define SCHED_BVT 0 -#define SCHED_ATROPOS 2 -#define SCHED_RROBIN 3 -/* these describe the intended direction used for a scheduler control or domain - * command */ +/* Set or get info? */ #define SCHED_INFO_PUT 0 #define SCHED_INFO_GET 1 @@ -23,48 +20,29 @@ */ struct sched_ctl_cmd { - u32 sched_id; /* 0 */ - u32 direction; /* 4 */ - union { /* 8 */ - struct bvt_ctl - { - /* IN variables. */ - u32 ctx_allow; /* 8: context switch allowance */ - } PACKED bvt; - - struct rrobin_ctl - { - /* IN variables */ - u64 slice; /* 8: round robin time slice */ - } PACKED rrobin; - } PACKED u; -} PACKED; /* 16 bytes */ + u32 sched_id; + u32 direction; + union { + struct bvt_ctl { + u32 ctx_allow; + } bvt; + } u; +}; struct sched_adjdom_cmd { - u32 sched_id; /* 0 */ - u32 direction; /* 4 */ - domid_t domain; /* 8 */ - u16 __pad0; - u32 __pad1; - union { /* 16 */ - struct bvt_adjdom - { - u32 mcu_adv; /* 16: mcu advance: inverse of weight */ - u32 warpback; /* 20: warp? */ - s32 warpvalue; /* 24: warp value */ - long long warpl; /* 32: warp limit */ - long long warpu; /* 40: unwarp time requirement */ - } PACKED bvt; - - struct atropos_adjdom - { - u64 nat_period; /* 16 */ - u64 nat_slice; /* 24 */ - u64 latency; /* 32 */ - u32 xtratime; /* 36 */ - } PACKED atropos; - } PACKED u; -} PACKED; /* 40 bytes */ + u32 sched_id; + u32 direction; + domid_t domain; + union { + struct bvt_adjdom { + u32 mcu_adv; /* mcu advance: inverse of weight */ + u32 warpback; /* warp? */ + s32 warpvalue; /* warp value */ + long long warpl; /* warp limit */ + long long warpu; /* unwarp time requirement */ + } bvt; + } u; +}; #endif /* __XEN_PUBLIC_SCHED_CTL_H__ */ diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index c9fdd23702..3e352f4fe8 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -30,7 +30,7 @@ struct scheduler { char *opt_name; /* option name for this scheduler */ unsigned int sched_id; /* ID for this scheduler */ - int (*init_scheduler) (); + int (*init_scheduler) (void); int (*init_idle_task) (struct exec_domain *); int (*alloc_task) (struct exec_domain *); void (*add_task) (struct exec_domain *); @@ -38,14 +38,12 @@ struct scheduler { void (*rem_task) (struct exec_domain *); void (*sleep) (struct exec_domain *); void (*wake) (struct exec_domain *); - void (*do_block) (struct exec_domain *); struct task_slice (*do_schedule) (s_time_t); int (*control) (struct sched_ctl_cmd *); int (*adjdom) (struct domain *, struct sched_adjdom_cmd *); void (*dump_settings) (void); void (*dump_cpu_state) (int); - int (*prn_state) (int); }; extern struct schedule_data schedule_data[]; -- 2.30.2